package com.sulent.frame.web.controller.test;

import cn.hutool.core.map.MapUtil;
import com.sulent.frame.file.utils.SubFileDemo;
import com.sulent.frame.file.utils.SubMinioClient;
import com.sulent.frame.web.service.MultiUploadService;
import io.minio.ListPartsResponse;
import io.minio.errors.*;
import io.minio.messages.Part;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @ClassName MultiUploadController
 * @Description: TODO
 * @Author Submerge.
 * @Since 2024/2/4 14:55
 * @Version 1.0
 */
@RestController
@RequestMapping("/multi")
public class MultiUploadController {

    @Autowired
    private MultiUploadService multiUploadService;


    @GetMapping("/init")
    public Object initMultiUploadTask(String bucketName,String fileName,String fileSize,Integer partCount){
        String uploadId = multiUploadService.initMultiUploadTask(bucketName,fileName,fileSize,partCount);
        return MapUtil.builder("uploadId",uploadId).build();
    }

    @PostMapping("/upload")
    public Object uploadPart(String uploadId, Long offset, Long length, Integer partNumber, Integer partSize, @RequestBody MultipartFile file){
        String etag = multiUploadService.uploadPart(uploadId,offset,length,partNumber,partSize,file);
        return MapUtil.builder("etag",etag).build();
    }

    @GetMapping("/complete")
    public Object completePart(String uploadId){
        String result  = multiUploadService.completePart(uploadId);
        return MapUtil.builder("result",result).build();
    }

    @GetMapping("/partList")
    public Object listMulti(String uploadId){
        List<Part> partList  = multiUploadService.listMulti(uploadId);
        return MapUtil.builder("partList",partList).build();
    }

    @GetMapping("/multiUploads")
    public Object listMultiUploads(String uploadId){
        Object o = multiUploadService.listMultiUploads(uploadId);
        return MapUtil.builder("multiUploads",o).build();
    }

    @GetMapping("/download")
    public Object downloadObject(String objectName){
        String filePath  = multiUploadService.downloadObject(objectName);
        return MapUtil.builder("filePath",filePath).build();
    }

    @GetMapping("/stateObject")
    public Object stateObject(String objectName){
        String etag  = multiUploadService.stateObject(objectName);
        return MapUtil.builder("etag",etag).build();
    }

    @GetMapping("/preSignedUrl")
    public Object preSignedUrl(String objectName){
        String url  = multiUploadService.preSignedUrl(objectName);
        return MapUtil.builder("url",url).build();
    }


    /**
     * 初始化任务，返回预上传ID
     * @return
     * @throws ServerException
     * @throws InsufficientDataException
     * @throws ErrorResponseException
     * @throws IOException
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeyException
     * @throws InvalidResponseException
     * @throws XmlParserException
     * @throws InternalException
     */
    @GetMapping("/init2")
    public Object createMultiUploadTask() throws ServerException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
        SubFileDemo subFileDemo = new SubFileDemo();
        SubMinioClient subMinioClient = subFileDemo.initClient();
        String uploadId = subFileDemo.initTask(subMinioClient);
        // 1. 根据文件名创建签名
        Map<String, Object> result = new HashMap<>();
        result.put("uploadId", uploadId);
        // 3. 请求Minio 服务，获取每个分块带签名的上传URL
        Map<String, String> reqParams = new HashMap<>();
        reqParams.put("uploadId", uploadId);
        List<String> partList = new ArrayList<>();
        // 4. 循环分块数 从0开始
        int chunkSize=16;
        for (int i = 0; i <= chunkSize; i++) {
            reqParams.put("partNumber", String.valueOf(i));
            String presignedObjectUrl = subFileDemo.getPresignedObjectUrl(subMinioClient,reqParams);
            result.put("chunk_" + i, presignedObjectUrl); // 添加到集合
        }
        return result;
    }

    /**
     * 分片上传完后合并
     *
     * @param objectName 文件全路径名称
     * @param uploadId   返回的uploadId
     * @return /
     */
    @GetMapping("/completeMultipartUpload3")
    public boolean completeMultipartUpload(String bucketName,String objectName, String uploadId) {
        try {
            Part[] parts = new Part[10000];
            SubFileDemo subFileDemo = new SubFileDemo();
            SubMinioClient subMinioClient = subFileDemo.initClient();
            ListPartsResponse listPartsResponse = subMinioClient.listParts("ai-model", null, objectName, 1000, 0, uploadId, null, null);
            int partNumber = 1;
            System.err.println(listPartsResponse.result().partList().size() + "========================");
            for (Part part : listPartsResponse.result().partList()) {
                parts[partNumber - 1] = new Part(partNumber, part.etag());
                partNumber++;
            }
            subMinioClient.completeMultipartUpload("ai-model", null, objectName, uploadId, parts, null, null);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }

        return true;
    }


}
